//1.instanceof  就是看 自身的prototype 等不等于原型链上的__proto__不停递归
const instanceof_ = (A, B) => {
  if (typeof A !== "object" || typeof A === null || typeof B !== "function") {
    return false
  }
  let prototype = B.prototype
  const __proto__ = A.__proto__
  while (true) {
    if (__proto__ === null) {
      return false
    }
    if (__proto__ === prototype) {
      return true
    }
    __proto__ = __proto__.__proto__
  }
}

//2.继承  ①class ②原型链  ③构造函数 ④组合
//②原型链
function parent() {
  this.age = 20
}
function child() {
  this.name = "李四"
}
child.prototype = new parent()
//③构造函数
function parent2() {
  this.age2 = 20
}
function child2(...arguments) {
  parent2.call(this, arguments)
}
//④组合 通过构造函数继承父类的实例  通过原型链继承父类的属性和方法
function parent3() {
  this.age = 40
}
function child3() {
  this.name = "老刘"
  parent3.call(this)
}
child3.prototype = new parent3()
//3.数组扁平化 用一个新的数组  遍历原数组 如果是数组的话先拼接新数组 再递归  如果 不是数组直接push进新数组
function flatten(arr) {
  let res = []
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      res = res.concat(flatten(arr[i]))
    } else {
      res.push(arr[i])
    }
  }
  return res
}
flatten([1, [2, [3, 2, 45]]])

//4.深拷贝
function deepClone(obj) {
  if (obj !== "object") return
  let newObj = obj instanceof Array ? [] : {}
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] =
        typeof obj[key] === "object" ? deepClone(obj[key]) : obj[key]
    }
  }
  return newObj
}
//5.发布订阅

//6.防抖
function debounce(callback, delay) {
  let timer
  return function () {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      callback().call(this)
    }, delay)
  }
}
//7.节流
function throttle(callback, delay) {
  let flag = true
  if (flag) {
    flag = false
    setTimeout(() => {
      callback().call(this)
      flag = true
    }, delay)
  }
}
//8.函数柯里化
function curry(fn) {
  let judge = (...args) => {
    if (args.length === fn.length) return fn(...args)
    return (...args) => judge(...args, ...args)
  }
}

function currys(fn) {
  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args)
    } else {
      return function (...args2) {
        return curried.apply(this, args.concat(args2))
      }
    }
  }
}
function add(x, y, z) {
  return x + y + z
}
const curryAdd = curry(add)
console.log(curryAdd(1)(2)(3)())
//9.call  apply  bind

//10.去重
//filter
function unique(arr) {
  let arr2 = arr.filter((item, index, self) => self.indexOf(item) === index)
}
